package ecom.shell;

import java.io.IOException;
import java.io.PrintStream;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import shell.Shell;
import shell.command.ShellCommandImpl;
import shell.command.ShellContext;
import ecom.ejb.AdminRemote;
import ecom.ejb.CustomerRemote;
import ecom.ejb.EuroConverterRemote;
import ecom.ejb.EuroConverterRemote.Devise;
import ecom.entity.ProductStoreRemote;
import exceptions.IdentifiantInvalide;
import exceptions.InstanceInvalide;

/**
 * eCommerce Application Sample for J2EE Training. Manipulation des magasins.
 * 
 * @author François Haurit
 * @version 1.0
 */
public final class StoreCommandImpl extends ShellCommandImpl {

    /**
     * Constructeur.
     * 
     * @param context
     *            Le contexte
     */
    public StoreCommandImpl(final ShellContext context) {
        super(context);
    }

    @Override
    public String getName() {
        return "store";
    }

    @Override
    public String getUsage() {
        return "store [-create <long productStoreId> <string productStoreAccountId> <string productStoreName> | -delete <long productStoreId> ]";
    }

    @Override
    public String getShortDescription() {
        return "Get list of all shops";
    }

    @Override
    public void execute(final String s, final PrintStream out,
            final PrintStream err) {
        String ligneDeCommande = s.trim();

        // Création
        Pattern patternCreate = Pattern.compile("^-create\\s(\\d+)\\s(\\w+)\\s(\\w+)$");

        // Suppression
        Pattern patternDelete = Pattern.compile("^-delete\\s(\\d+)$");

        /*
         * Préparation de la sortie
         */
        Document dom = null;
        Element root = null;
        StringBuilder texte = null;
        boolean erreur = false;

        if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
            // Si TEXTE
            texte = new StringBuilder();
        } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
            // Si XML
            try {
                dom = Output.getNewDocument();
                root = dom.createElement(this.getName() + "Command");
                dom.appendChild(root);
            } catch (final ParserConfigurationException e) {
                err.println(e.getMessage());
            }
        }

        // Aucun argument -> Liste
        if (ligneDeCommande.trim().equals("")) {
            out.println("Affichage de tous les magasin");

            /*
             * Récupération de la liste des produits
             */
            List<ProductStoreRemote> magasins = ((CustomerRemote) this.getContexte().getVar(EcomShellConstantes.CUSTOMER)).listProductStores();

            /*
             * Affichage
             */
            if (magasins != null) {
                out.println("Affichage des magasin:");

                ProductStoreRemote cr = null;
                Iterator<ProductStoreRemote> it = magasins.iterator();
                while (it.hasNext()) {
                    cr = it.next();
                    /*
                     * Gestion de la sortie
                     */
                    if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
                        /*
                         * Si TEXTE
                         */
                        texte.append("\t" + Output.toString(cr, (Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                                ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER)))
                                + Shell.RETOUR_CHARIOT);
                    } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                        /*
                         * Si XML
                         */
                        root.appendChild(Output.toXml(cr,
                                dom,
                                (Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                                ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER))));
                    }
                }
            } else {
                out.println("Pas de magasin à afficher");
            }
        } else if (patternCreate.matcher(ligneDeCommande).find()) {
            /*
             * Extraction des arguments
             */
            String[] arguments = ligneDeCommande.replace("-create ", "").split(
                    " ");

            try {
                /*
                 * Création du magasin
                 */
                out.println("Création du magasin");
                out.println("Référence : "
                        + Long.valueOf(arguments[0].toString()));
                out.println("Compte : " + arguments[1]);
                out.println("Nom : " + arguments[2]);

                ProductStoreRemote magasin = ((AdminRemote) this.getContexte().getVar(EcomShellConstantes.ADMIN)).createProductStore(
                        Long.valueOf(arguments[0]), arguments[1], arguments[2]);

                /*
                 * Gestion de la sortie
                 */
                if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
                    /*
                     * Si TEXTE
                     */
                    texte.append("\t"
                            + Output.toString(
                            magasin,
                            (Devise) this.getContexte().getVar(EcomShellConstantes.CURRENT_CURRENCY),
                            ((EuroConverterRemote) this.getContexte().getVar(EcomShellConstantes.CONVERTER)))
                            + Shell.RETOUR_CHARIOT);
                } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                    /*
                     * Si XML
                     */
                    root.appendChild(Output.toXml(
                            magasin,
                            dom,
                            (Devise) this.getContexte().getVar(
                            EcomShellConstantes.CURRENT_CURRENCY),
                            ((EuroConverterRemote) this.getContexte().getVar(
                            EcomShellConstantes.CONVERTER))));
                }
            } catch (final NumberFormatException e) {
                err.println(e.getMessage());
            } catch (final IdentifiantInvalide e) {
                err.println(e.getMessage());
            } catch (final InstanceInvalide e) {
                err.println(e.getMessage());
            }
        } else if (patternDelete.matcher(ligneDeCommande).find()) {
            /*
             * Extraction des arguments
             */
            String arguments = ligneDeCommande.replace("-delete ", "");

            /*
             * Création du compte
             */
            out.println("Suppression du magasin " + arguments);

            /*
             * Récupération du compte
             */
            ProductStoreRemote magasin;
            try {
                magasin = ((AdminRemote) this.getContexte().getVar(
                        EcomShellConstantes.ADMIN)).getProductStore(Long.valueOf(arguments));

                ((AdminRemote) this.getContexte().getVar(
                        EcomShellConstantes.ADMIN)).removeProductStore(magasin);
            } catch (final IdentifiantInvalide e) {
                err.println(e.getMessage());
            }
        } else {
            out.println("Usage: " + this.getUsage());
            erreur = true;
        }

        if (!erreur) {
            /*
             * Restitution de la sortie
             */
            if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.TEXT_MIMETYPE)) {
                /*
                 * Si TEXTE
                 */
                out.println(texte.toString());
            } else if (this.getContexte().getVar(EcomShellConstantes.OUTPUT_MIME_FORMAT).equals(EcomShellConstantes.XML_MIMETYPE)) {
                try {
                    out.println(Output.toString(dom));
                } catch (final IOException e) {
                    err.println(e.getMessage());
                }
            }
        }
    }
}
